#include "bsp_rtc.h"


static void BSP_Rtc_init(emRTC_Set Settime);

//RTC时钟配置,秒输出校时的时候调用
void RTC_ClkCfg(void)
{
    Sysctrl_SetRCHTrim(SysctrlRchFreq24MHz);       //内部高速时钟频率TRIM值加载    
    Sysctrl_SetRTCAdjustClkFreq(SysctrlRTC24MHz);  //补偿高速时钟源   
    Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);  //使能RCL时钟
}

 
// RTC 初始化要注意,MCU上电复位后需要初始化且设置时间,其他复位如Boot跳转OTA升级等不需要初始化
void BSP_IntelligentRtc_init(void)
{
	if(Reset_GetFlag(ResetFlagMskPor1_5V) || Reset_GetFlag(ResetFlagMskRstb))
	{	
		Reset_ClearFlag(ResetFlagMskPor1_5V);
		Reset_ClearFlag(ResetFlagMskRstb);
		printf("MCU reset boot,RTC set default time!!\r\n");	
		BSP_Rtc_init(SetTime);      //RTC初始化且设置时间初值   
	}
	else  // watchdog 复位, boot跳转复位,均不修改时间
	{	
		BSP_Rtc_init(NotSetTime);     
	}
}


static void BSP_Rtc_init(emRTC_Set Settime)
{
	stc_rtc_initstruct_t RtcInitStruct;
	stc_rtc_alarmtime_t RtcAlmStruct;

	DDL_ZERO_STRUCT(RtcInitStruct);                     
	DDL_ZERO_STRUCT(RtcAlmStruct);
		
    Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE);   //RTC模块时钟打开 
#if 1	
	Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);			//内部低速时钟
	RtcInitStruct.rtcClksrc = RtcClkRcl;                    
#else 
	Sysctrl_ClkSourceEnable(SysctrlClkXTL,TRUE);            //配置XTL作为RTC时钟
	RtcInitStruct.rtcClksrc = RtcClkXtl;                    //外部低速时钟
#endif
	
	//MCU非上电复位后这些寄存器的值不会丢失	
	if(Settime == SetTime)
	{	
#if 0
		RtcInitStruct.rtcPrdsel.rtcPrdsel = RtcPrdx;           //周期中断类型PRDX
		RtcInitStruct.rtcPrdsel.rtcPrdx = 1;                   //每隔xs产生一次周期中断：(prdx +1)/2 = xs
#else
		RtcInitStruct.rtcPrdsel.rtcPrdsel = RtcPrds;          //由PRDS产生周期中断,时间间隔范围更大 
		RtcInitStruct.rtcPrdsel.rtcPrds = Rtc1H;
#endif		
		
		RtcInitStruct.rtcAmpm = RtcPm;                          //24小时制
		
		RtcInitStruct.rtcTime.u8Second = 0x55;  //设置初始时间
		RtcInitStruct.rtcTime.u8Minute = 0x59;
		RtcInitStruct.rtcTime.u8Hour   = 0x23;  /*实际数值为23*/
		RtcInitStruct.rtcTime.u8Day    = 0x18;  /*实际数值为18*/
		RtcInitStruct.rtcTime.u8DayOfWeek = 0x04;
		RtcInitStruct.rtcTime.u8Month  = 0x06;
		RtcInitStruct.rtcTime.u8Year   = 0x21;   	    // 2021年
		RtcInitStruct.rtcCompen = RtcCompenEnable;
		RtcInitStruct.rtcCompValue = 0;            //补偿值 根据实际情况进行补偿
		Rtc_Init(&RtcInitStruct);

		RtcAlmStruct.RtcAlarmMinute = 0x02;
		RtcAlmStruct.RtcAlarmHour = 0x10;
		RtcAlmStruct.RtcAlarmWeek = 0x7f;          //从周一到周日每天10:02启动一次闹铃
		Rtc_SetAlarmTime(&RtcAlmStruct);           //配置闹铃时间

		Rtc_AlmIeCmd(TRUE);                          //使能闹钟中断
		EnableNvic(RTC_IRQn, IrqLevel3, TRUE);       //使能RTC中断向量
		Rtc_Cmd(TRUE);                               //使能RTC开始计数
		Rtc_StartWait();                             //启动RTC计数，如果要立即切换到低功耗，需要执行此函数    	
	}  
}


/*设置时间,用于校时,把结构体时间写入寄存器*/
en_result_t BSP_Rtc_SetTime(struct tm *pstcTimeDate)
{
	en_result_t enRet = Error;
	stc_rtc_time_t bcd_time;
	Rtc_Cmd(FALSE);    //RTC停止计数

	bcd_time.u8Hour = DEC2BCD(pstcTimeDate->tm_hour);
	bcd_time.u8Minute = DEC2BCD(pstcTimeDate->tm_min);
	bcd_time.u8Second = DEC2BCD(pstcTimeDate->tm_sec);

	bcd_time.u8Year = DEC2BCD(pstcTimeDate->tm_year - 100); /*计算的起始年份不同*/	
	bcd_time.u8Month = DEC2BCD(pstcTimeDate->tm_mon + 1);
	bcd_time.u8Day = DEC2BCD(pstcTimeDate->tm_mday);
	/*星期取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
	bcd_time.u8DayOfWeek = pstcTimeDate->tm_wday; 
	
	enRet = Rtc_SetTime(&bcd_time);
	
	if(enRet == Ok)
	{
		Rtc_Cmd(TRUE);    //使能RTC开始计数
		Rtc_StartWait(); 	
		return Ok;		
	}
	return enRet;	
}



/**
 *************************************************************************
 ** \brief : 年月日周为10进制,不需要转换
 **
 **
 ** \param 1 : stcReadTime, 保存时间结构体
 ** 
 ** \retval :  en_result_t                              
 **************************************************************************/
en_result_t BSP_Rtc_ReadDateTime(struct tm *pstcTimeDate)
{		
	stc_rtc_time_t bcd_time;	
	Rtc_ReadDateTime(&bcd_time);	
	
	pstcTimeDate->tm_hour = BCD2DEC(bcd_time.u8Hour);
	pstcTimeDate->tm_min = BCD2DEC(bcd_time.u8Minute);
	pstcTimeDate->tm_sec = BCD2DEC(bcd_time.u8Second);
	
	pstcTimeDate->tm_year = 100 + BCD2DEC(bcd_time.u8Year); /*计算的起始年份不同*/
	pstcTimeDate->tm_mon = BCD2DEC(bcd_time.u8Month) - 1;  
	pstcTimeDate->tm_mday = BCD2DEC(bcd_time.u8Day);
	pstcTimeDate->tm_wday = BCD2DEC(bcd_time.u8DayOfWeek); /*星期取值区间为[0,6]，其中0代表星期天，1代表星期一，以此类推 */
	
	return Ok;	
}



/**
 *************************************************************************
 ** \FunctionName : 
 ** \brief : rtc 采用秒中断,更新时间结构体
 **
 ** \param 1 : stcReadTime, 保存时间结构体
 ** 
 ** \retval : void                            
 **************************************************************************/
void Rtc_IRQHandler(void)
{
	if(Rtc_GetPridItStatus()) //在周期中断,1hour唤醒一次 
    {   
        Rtc_ClearPrdfItStatus();             //清除中断标志位
        if(TRUE == Gpio_GetInputIO(GpioPortD, GpioPin5))
        {
            Gpio_WriteOutputIO(GpioPortD, GpioPin5, FALSE);    //输出低，熄灭LED     
        }            
        else
        {
            Gpio_WriteOutputIO(GpioPortD, GpioPin5, TRUE);     //输出高，点亮LED   
        }  	
		//Rtc_ReadDateTime_dec(&RTCTime.RealTime);	
		// 发出一个信号量,给某个线程去采集水量数据

		// 
    }
	
	if(Rtc_GetAlmfItStatus()) //闹铃中断,每天到时间点进入一次,用于唤醒上报月冻结数据
    {
        Rtc_ClearAlmfItStatus();    //清中断标志位,唤醒mcu
        
    }
}

// 2小时唤醒一次很难调试,先用短一点的时间调试,这部分在最后做集成>
// 校时后,与NB校时,校时成功后,


